#include "temperature.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <pthread.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include <stdarg.h>



// 定时器参数结构体
typedef struct {
    lv_obj_t *obj;       // UI对象
    int state;           // 开关状态
    bool visible;        // 面板可见性
    char *text;          // 标签文本
    int value;           // 圆弧值
} TimerParam;

// 静态变量
static int adc_fd = -1;
static int led_fd = -1;            // LED硬件 (GPIO120)
static int beep_fd = -1;           // 蜂鸣器硬件 (GPIO111)
static pthread_t monitor_thread;
static volatile int thread_running = 0;
float current_temperature = 25.0f;  // 当前温度
float last_valid_temperature = 25.0f; // 最后一次有效温度
float previous_temperature = 25.0f; // 上一次温度值（用于检测变化）
int is_initialized = 0;
int temperature_module_is_initialized(void) {
    return is_initialized;
}
int adc_consecutive_failures = 0;    // ADC连续失败计数

// 设备状态变量
int led_state = 0;          // LED实际状态（1:开,0:关）
int beep_state = 0;         // 蜂鸣器实际状态（1:开,0:关）
int desired_led_state = 0;  // 自动模式下期望的LED状态
int desired_beep_state = 0; // 自动模式下期望的蜂鸣器状态
int manual_led_override = 0; // 1:LED手动控制模式（优先级最高）
int manual_beep_override = 0; // 1:蜂鸣器手动控制模式
int temperature_changed = 0; // 标记温度是否发生变化

// 同步锁
pthread_mutex_t temp_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t control_mutex = PTHREAD_MUTEX_INITIALIZER;

// ADC路径 - 根据实际硬件修改
static char adc_path[128] = "/sys/bus/iio/devices/iio:device0/in_voltage6_raw";

// UI有效性检查
#define UI_VALID(obj) (obj != NULL && lv_obj_is_valid(obj))

// 外部UI组件声明（与实际UI文件对应）
extern lv_obj_t *ui_normalPanel;
extern lv_obj_t *ui_WarningPanel;
extern lv_obj_t *ui_ledSwitch;
extern lv_obj_t *ui_beepSwitch;
extern lv_obj_t *ui_temperaturevalue;
extern lv_obj_t *ui_temperatureArc;

// 函数声明
static void set_switch_state_cb(lv_timer_t *t);
static void set_panel_visible_cb(lv_timer_t *t);
static void update_label_cb(lv_timer_t *t);
static void update_arc_cb(lv_timer_t *t);
static void apply_auto_control(void);
static void log_message(const char *format, ...);
static void check_temperature_change(float new_temp, float old_temp);

/**
 * 日志输出函数，带时间戳
 */
static void log_message(const char *format, ...) {
    time_t now;
    struct tm *timeinfo;
    char time_str[20];
    
    time(&now);
    timeinfo = localtime(&now);
    strftime(time_str, sizeof(time_str), "%H:%M:%S", timeinfo);
    
    printf("[%s] ", time_str);
    
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
}

/**
 * 检查温度是否发生变化（超过0.5℃视为变化）
 */
static void check_temperature_change(float new_temp, float old_temp) {
    if (fabs(new_temp - old_temp) > 0.5f) {
        pthread_mutex_lock(&control_mutex);
        temperature_changed = 1;
        // 温度变化时，仅在27.1℃-100℃范围重置手动控制标记
        if (new_temp >= TEMP_HIGH_LOW && new_temp <= 100.0f) {
            manual_led_override = 0;
            //log_message("温度变化超过0.5℃，LED控制权交回自动系统\n");
        }
        // 蜂鸣器控制逻辑保持不变
        manual_beep_override = 0;
        pthread_mutex_unlock(&control_mutex);
    } else {
        temperature_changed = 0;
    }
}

/**
 * LED开关回调函数 - 手动控制时立即接管控制权
 */
void ui_ledSwitch_event_handler(lv_obj_t *obj, lv_event_t *event) {
    if (event->code == LV_EVENT_VALUE_CHANGED) {
        int state = lv_obj_has_state(obj, LV_STATE_CHECKED) ? 1 : 0;
        pthread_mutex_lock(&control_mutex);
        
        // 仅在27.1℃-100℃范围内允许手动控制
        if (current_temperature >= TEMP_HIGH_LOW && current_temperature <= 100.0f) {
            manual_led_override = 1;
            led_state = state;
            
            // 立即控制硬件LED
            if (led_fd != -1) {
                write(led_fd, state ? "1" : "0", 1);
                fsync(led_fd);
            }
            
            log_message("LED手动控制: %s (已接管控制权)\n", state ? "开启" : "关闭");
        }
        pthread_mutex_unlock(&control_mutex);
    }
}

/**
 * 蜂鸣器开关回调函数 - 手动控制时立即接管控制权
 */
void ui_beepSwitch_event_handler(lv_obj_t *obj, lv_event_t *event) {
    if (event->code == LV_EVENT_VALUE_CHANGED) {
        int state = lv_obj_has_state(obj, LV_STATE_CHECKED) ? 1 : 0;
        pthread_mutex_lock(&control_mutex);
        
        // 手动控制标记置位，接管控制权
        manual_beep_override = 1;
        beep_state = state;
        
        // 控制硬件蜂鸣器
        if (beep_fd != -1) {
            write(beep_fd, state ? "1" : "0", 1);
            fsync(beep_fd);
        }
        
        log_message("蜂鸣器手动控制: %s (已接管控制权)\n", state ? "开启" : "关闭");
        pthread_mutex_unlock(&control_mutex);
    }
}

/**
 * 设置开关控件状态（LVGL线程安全）
 */
void set_switch_state(lv_obj_t *sw, int state) {
    if (!UI_VALID(sw)) return;
    
    TimerParam *param = malloc(sizeof(TimerParam));
    param->obj = sw;
    param->state = state;
    
    lv_timer_t *timer = lv_timer_create(set_switch_state_cb, 0, param);
    lv_timer_set_repeat_count(timer, 1);
}

/**
 * 开关状态更新回调
 */
static void set_switch_state_cb(lv_timer_t *t) {
    TimerParam *param = (TimerParam *)t->user_data;
    if (!param || !UI_VALID(param->obj)) {
        free(param);
        return;
    }

    if (param->state) {
        lv_obj_add_state(param->obj, LV_STATE_CHECKED);
    } else {
        lv_obj_clear_state(param->obj, LV_STATE_CHECKED);
    }
    lv_obj_invalidate(param->obj);
    
    free(param);
}

/**
 * ADC值转温度
 */
static float adc_to_temperature(int adc_value) {
    if (adc_value < ADC_MIN_VALUE) adc_value = ADC_MIN_VALUE;
    if (adc_value > ADC_MAX_VALUE) adc_value = ADC_MAX_VALUE;
    
    float ratio = (adc_value - ADC_MIN_VALUE) / (float)(ADC_MAX_VALUE - ADC_MIN_VALUE);
    return ratio * 100.0f;
}

/**
 * 读取并解析ADC原始值
 */
static int read_adc_value(void) {
    if (adc_fd == -1) {
        log_message("ADC错误: 文件描述符未打开\n");
        return -1;
    }

    // 尝试重新打开ADC设备（增加重试机制）
    int retry_count = 0;
    while (lseek(adc_fd, 0, SEEK_SET) == -1 && retry_count < 3) {
        close(adc_fd);
        adc_fd = open(adc_path, O_RDONLY);
        if (adc_fd == -1) {
            log_message("ADC错误: 重新打开失败 (尝试 %d/3): %s\n", 
                   retry_count + 1, strerror(errno));
            retry_count++;
            usleep(100000); // 等待100ms后重试
        } else {
            log_message("ADC信息: 重新打开成功\n");
            break;
        }
    }

    if (adc_fd == -1) {
        log_message("ADC错误: 超过最大重试次数，无法打开设备\n");
        return -1;
    }

    char buf[32] = {0};
    ssize_t bytes_read = read(adc_fd, buf, sizeof(buf) - 1);
    if (bytes_read <= 0) {
        log_message("ADC错误: 读取失败，返回值: %zd, 错误: %s\n", 
               bytes_read, strerror(errno));
        return -1;
    }

    // 清理缓冲区，处理换行和空格
    for (int i = 0; i < bytes_read; i++) {
        if (buf[i] == '\n' || buf[i] == ' ' || buf[i] == '\r' || buf[i] == '\0') {
            buf[i] = '\0';
            break;
        }
    }

    // 尝试解析数值
    char *endptr;
    errno = 0; // 重置错误号
    long val = strtol(buf, &endptr, 10);

    // 解析错误检查
    if (*endptr != '\0') {
        log_message("ADC错误: 解析失败，非数字内容: %s\n", buf);
        return -1;
    }
    if (errno == ERANGE) {
        log_message("ADC错误: 数值超出范围: %s\n", buf);
        return -1;
    }
    
    return (int)val;
}

/**
 * 应用自动控制逻辑（仅在非手动模式下）
 */
static void apply_auto_control(void) {
    pthread_mutex_lock(&control_mutex);
    
    // LED控制逻辑：仅在未手动操作时应用自动控制
    if (!manual_led_override) {
        if (led_state != desired_led_state) {
            led_state = desired_led_state;
            if (led_fd != -1) {
                write(led_fd, desired_led_state ? "1" : "0", 1);
                fsync(led_fd);
            }
            set_switch_state(ui_ledSwitch, desired_led_state);
        }
    }
    
    // 蜂鸣器控制逻辑：仅在未手动操作时应用自动控制
    if (!manual_beep_override) {
        if (beep_state != desired_beep_state) {
            beep_state = desired_beep_state;
            if (beep_fd != -1) {
                write(beep_fd, desired_beep_state ? "1" : "0", 1);
                fsync(beep_fd);
            }
            set_switch_state(ui_beepSwitch, desired_beep_state);
        }
    }
    
    pthread_mutex_unlock(&control_mutex);
}

/**
 * 控制面板显示状态
 */
static void set_panel_visible(lv_obj_t *panel, bool visible) {
    if (!UI_VALID(panel)) return;
    
    TimerParam *param = malloc(sizeof(TimerParam));
    param->obj = panel;
    param->visible = visible;
    
    lv_timer_t *timer = lv_timer_create(set_panel_visible_cb, 0, param);
    lv_timer_set_repeat_count(timer, 1);
}

/**
 * 面板显示状态更新回调
 */
static void set_panel_visible_cb(lv_timer_t *t) {
    TimerParam *param = (TimerParam *)t->user_data;
    if (!param || !UI_VALID(param->obj)) {
        free(param);
        return;
    }

    if (param->visible) {
        lv_obj_clear_flag(param->obj, LV_OBJ_FLAG_HIDDEN);
    } else {
        lv_obj_add_flag(param->obj, LV_OBJ_FLAG_HIDDEN);
    }
    lv_obj_invalidate(param->obj);
    
    free(param);
}

/**
 * 计算LED闪烁延迟（27.1℃-100℃温度越高频率越快）
 */
static unsigned int calculate_blink_delay(float temp) {
    if (temp < TEMP_HIGH_LOW) return 1000;
    if (temp > 100) temp = 100;  // 上限100℃
    
    // 温度越高，延迟越小，频率越快
    // 27.1℃时约1000ms，100℃时约50ms
    float ratio = (temp - TEMP_HIGH_LOW) / (100 - TEMP_HIGH_LOW);
    return 1000 - (unsigned int)(ratio * 950);
}

/**
 * 温度标签更新回调
 */
static void update_label_cb(lv_timer_t *t) {
    TimerParam *param = (TimerParam *)t->user_data;
    if (!param || !UI_VALID(param->obj) || !param->text) {
        if (param) free(param->text);
        free(param);
        return;
    }

    lv_label_set_text(param->obj, param->text);
    lv_obj_invalidate(param->obj);
    
    free(param->text);
    free(param);
}

/**
 * 温度圆弧更新回调
 */
static void update_arc_cb(lv_timer_t *t) {
    TimerParam *param = (TimerParam *)t->user_data;
    if (!param || !UI_VALID(param->obj)) {
        free(param);
        return;
    }

    lv_arc_set_value(param->obj, param->value);
    lv_obj_invalidate(param->obj);
    
    free(param);
}

/**
 * 温度监控线程 - 核心控制逻辑
 */
static void *temperature_monitor_thread(void *arg) {
    int adc_value;
    int led_blink_state = 0;  // 用于自动模式下的LED闪烁
    unsigned int blink_delay = 1000;
    char temp_str[16];

    while (thread_running) {
        // 读取ADC值
        adc_value = read_adc_value();
        if (adc_value != -1) {
            adc_consecutive_failures = 0;
            pthread_mutex_lock(&temp_mutex);
            previous_temperature = current_temperature;  // 保存旧温度
            current_temperature = adc_to_temperature(adc_value);
            last_valid_temperature = current_temperature;
            
            // 检查温度是否发生显著变化
            check_temperature_change(current_temperature, previous_temperature);
            
            pthread_mutex_unlock(&temp_mutex);
            //log_message("温度: %.1f℃ (ADC值: %d)\n", current_temperature, adc_value);
        } else {
            adc_consecutive_failures++;
            if (adc_consecutive_failures >= 5) {
                log_message("ADC连续失败超过5次，使用最后一次有效温度: %.1f℃\n", 
                       last_valid_temperature);
                pthread_mutex_lock(&temp_mutex);
                previous_temperature = current_temperature;
                current_temperature = last_valid_temperature;
                check_temperature_change(current_temperature, previous_temperature);
                pthread_mutex_unlock(&temp_mutex);
            }
        }

        // 更新温度显示
        pthread_mutex_lock(&temp_mutex);
        float temp = current_temperature;
        pthread_mutex_unlock(&temp_mutex);

        if (UI_VALID(ui_temperaturevalue)) {
            snprintf(temp_str, sizeof(temp_str), "%.1f℃", (double)temp);
            TimerParam *param = malloc(sizeof(TimerParam));
            param->obj = ui_temperaturevalue;
            param->text = strdup(temp_str);
            lv_timer_t *label_timer = lv_timer_create(update_label_cb, 0, param);
            lv_timer_set_repeat_count(label_timer, 1);
        }

        // 更新温度圆弧
        if (UI_VALID(ui_temperatureArc)) {
            int arc_value = (int)(temp / 100.0f * 100);
            TimerParam *param = malloc(sizeof(TimerParam));
            param->obj = ui_temperatureArc;
            param->value = arc_value;
            lv_timer_t *arc_timer = lv_timer_create(update_arc_cb, 0, param);
            lv_timer_set_repeat_count(arc_timer, 1);
        }

        // 根据温度设置期望状态（仅在非手动模式下生效）
        pthread_mutex_lock(&control_mutex);
        if (temp >= TEMP_NORMAL_LOW && temp <= TEMP_NORMAL_HIGH) {
            // 正常范围（18℃-27℃）
            set_panel_visible(ui_normalPanel, true);
            set_panel_visible(ui_WarningPanel, false);
            desired_led_state = 0;      // 自动模式下LED默认关闭
            desired_beep_state = 0;     // 蜂鸣器默认关闭
        }
        else if (temp >= 0 && temp <= TEMP_LOW_HIGH) {
            // 低温范围（0℃-17.9℃）
            set_panel_visible(ui_normalPanel, false);
            set_panel_visible(ui_WarningPanel, true);
            desired_led_state = 1;      // 自动模式下LED默认常亮
            desired_beep_state = 1;     // 蜂鸣器默认开启
        }
        else if (temp >= TEMP_HIGH_LOW && temp <= TEMP_HIGH_HIGH) {
            // 高温范围（27.1℃-34.9℃）
            set_panel_visible(ui_normalPanel, false);
            set_panel_visible(ui_WarningPanel, true);
            blink_delay = calculate_blink_delay(temp);
            
            // 更新闪烁状态（仅用于自动模式）
            led_blink_state = !led_blink_state;
            desired_led_state = led_blink_state;
            // 确保UI开关显示为开启状态
            set_switch_state(ui_ledSwitch, 1);
            desired_beep_state = 0;     // 蜂鸣器默认关闭
        }
        else if (temp >= TEMP_ALARM) {
            // 35℃及以上
            set_panel_visible(ui_normalPanel, false);
            set_panel_visible(ui_WarningPanel, true);
            blink_delay = calculate_blink_delay(temp);
            
            // 更新闪烁状态（仅用于自动模式）
            led_blink_state = !led_blink_state;
            desired_led_state = led_blink_state;
            // 确保UI开关显示为开启状态
            set_switch_state(ui_ledSwitch, 1);
            desired_beep_state = 1;     // 蜂鸣器默认开启
        }
        pthread_mutex_unlock(&control_mutex);

        // 应用控制（手动模式下会忽略自动设置）
        apply_auto_control();

        // 根据模式调整延迟
        if ((temp >= TEMP_HIGH_LOW && temp <= TEMP_HIGH_HIGH) || temp >= TEMP_ALARM) {
            usleep(blink_delay * 1000);
        } else {
            usleep(1000000);  // 非高温模式1秒刷新一次
        }
    }
    return NULL;
}

/**
 * GPIO初始化
 */
static int gpio_init(int gpio_num, const char *name) {
    int fd;
    char path[64];

    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d", gpio_num);
    if (access(path, F_OK) != 0) {
        fd = open("/sys/class/gpio/export", O_WRONLY);
        if (fd == -1) {
            fprintf(stderr, "%s导出GPIO %d失败: %s\n", name, gpio_num, strerror(errno));
            return -1;
        }
        dprintf(fd, "%d", gpio_num);
        close(fd);
        usleep(200000);
    }

    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", gpio_num);
    fd = open(path, O_WRONLY);
    if (fd == -1) {
        fprintf(stderr, "%s设置GPIO %d方向失败: %s\n", name, gpio_num, strerror(errno));
        return -1;
    }
    write(fd, "out", 3);
    close(fd);
    usleep(100000);

    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", gpio_num);
    fd = open(path, O_WRONLY);
    if (fd == -1) {
        fprintf(stderr, "%s打开GPIO %d值文件失败: %s\n", name, gpio_num, strerror(errno));
        int unexport_fd = open("/sys/class/gpio/unexport", O_WRONLY);
        if (unexport_fd != -1) {
            dprintf(unexport_fd, "%d", gpio_num);
            close(unexport_fd);
        }
        return -1;
    }
    log_message("%s初始化成功 (GPIO %d)\n", name, gpio_num);
    return fd;
}

/**
 * 模块初始化
 */
int adc_display_init(void) {
    if (is_initialized) return 0;

    log_message("初始化ADC路径: %s\n", adc_path);
    // 初始化ADC
    adc_fd = open(adc_path, O_RDONLY);
    if (adc_fd == -1) {
        fprintf(stderr, "打开ADC失败(%s): %s\n", adc_path, strerror(errno));
        log_message("警告: ADC初始化失败，将使用默认温度\n");
    } else {
        log_message("ADC初始化成功\n");
    }

    // 初始化LED (GPIO120)和蜂鸣器 (GPIO111)
    led_fd = gpio_init(120, "LED");
    beep_fd = gpio_init(111, "蜂鸣器");

    // 初始状态
    manual_led_override = 0;       // 初始未手动操作
    manual_beep_override = 0;
    led_state = 0;
    beep_state = 0;
    desired_led_state = 0;
    desired_beep_state = 0;
    temperature_changed = 0;

    // 初始UI状态
    set_panel_visible(ui_normalPanel, true);
    set_panel_visible(ui_WarningPanel, false);
    set_switch_state(ui_ledSwitch, 0);
    set_switch_state(ui_beepSwitch, 0);

    is_initialized = 1;
    log_message("温度模块初始化完成\n");
    return 0;
}

/**
 * 启动监控线程
 */
void adc_display_start(void) {
    if (!is_initialized || thread_running) return;

    thread_running = 1;
    if (pthread_create(&monitor_thread, NULL, temperature_monitor_thread, NULL) != 0) {
        fprintf(stderr, "创建线程失败: %s\n", strerror(errno));
        thread_running = 0;
    } else {
        log_message("温度监控线程已启动\n");
    }
}

/**
 * 停止监控线程
 */
void adc_display_stop(void) {
    if (!thread_running) return;

    thread_running = 0;
    pthread_join(monitor_thread, NULL);
}

/**
 * 清理模块资源
 */
void adc_display_cleanup(void) {
    if (!is_initialized) return;

    adc_display_stop();

    // 清理LED资源 (GPIO120)
    if (led_fd != -1) {
        write(led_fd, "0", 1);
        fsync(led_fd);
        close(led_fd);
        int unexport_fd = open("/sys/class/gpio/unexport", O_WRONLY);
        if (unexport_fd != -1) {
            dprintf(unexport_fd, "120");
            close(unexport_fd);
        }
        led_fd = -1;
    }

    // 清理蜂鸣器资源 (GPIO111)
    if (beep_fd != -1) {
        write(beep_fd, "0", 1);
        fsync(beep_fd);
        close(beep_fd);
        int unexport_fd = open("/sys/class/gpio/unexport", O_WRONLY);
        if (unexport_fd != -1) {
            dprintf(unexport_fd, "111");
            close(unexport_fd);
        }
        beep_fd = -1;
    }

    // 清理ADC资源
    if (adc_fd != -1) {
        close(adc_fd);
        adc_fd = -1;
    }

    pthread_mutex_destroy(&temp_mutex);
    pthread_mutex_destroy(&control_mutex);

    is_initialized = 0;
    current_temperature = 25.0f;
    log_message("温度模块资源已清理\n");
}

/**
 * 获取当前温度
 */
float get_current_temperature(void) {
    float temp;
    pthread_mutex_lock(&temp_mutex);
    temp = current_temperature;
    pthread_mutex_unlock(&temp_mutex);
    return temp;
}

/**
 * 手动控制LED（外部调用接口）
 */
void manual_led_control(int state) {
    pthread_mutex_lock(&control_mutex);
    // 仅在27.1℃-100℃范围内允许手动控制
    if (current_temperature >= TEMP_HIGH_LOW && current_temperature <= 100.0f) {
        manual_led_override = 1;  // 标记为手动控制
        led_state = state;
        if (led_fd != -1) {
            write(led_fd, state ? "1" : "0", 1);
            fsync(led_fd);
        }
        set_switch_state(ui_ledSwitch, state);
    }
    pthread_mutex_unlock(&control_mutex);
}

/**
 * 手动控制蜂鸣器（外部调用接口）
 */
void manual_beep_control(int state) {
    pthread_mutex_lock(&control_mutex);
    manual_beep_override = 1;
    beep_state = state;
    if (beep_fd != -1) {
        write(beep_fd, state ? "1" : "0", 1);
        fsync(beep_fd);
    }
    set_switch_state(ui_beepSwitch, state);
    pthread_mutex_unlock(&control_mutex);
}
